#ifndef PJAPIUAACCOUNTHANDLER_H
#define PJAPIUAACCOUNTHANDLER_H

#include "pjapiuaaccount.h"
#include "pjapiuaaccountcallback.h"
#include "pjapicallinfo.h"

#ifdef __cplusplus
extern "C"{
#endif

#include <pjsua-lib/pjsua.h>
#include <pjsua-lib/pjsua_internal.h>

#ifdef __cplusplus
}
#endif

class PjApiUaAccountCallback;
class PjApiUaAccountHandler
{
public:
    PjApiUaAccountHandler();

    ~PjApiUaAccountHandler();

    void start();

    PjApiUaAccount* getAccount() const
    {
        return m_account;
    }

    PjApiUaAccountCallback *getAccountCallback() const
    {
        return m_accountCallback;
    }

    int getTransportID() const
    {
        return m_transportID;
    }

    void notifyServerRegistry(bool flag);

    void setAccountCallback(PjApiUaAccountCallback *callback);

    void setAccount(PjApiUaAccount *account);

    void setTransportID(int id);

    // To be refactored, implement transport config class
    // Here use the default configuration
    void setTransportConfig();

    void setRtpPort(int port);

    void setNullDevice();

    bool verifyUrl(const std::string url);

    // call section
    //need to be refactored since the pjsua_msg_data struct
    //Here we use the pjsua_msg_data

    int makeCall2( const std::string dst_uri,
                    void *user_data=0,
                    const pjsua_msg_data *msg_data=0);

    int makeCall( const std::string dst_uri,
                    void *user_data=0,
                    const std::string content_type="",
                    const std::string content="");

    int acceptCall(int call_id);

    int hangupCall2(int call_id,
                    int code,
                    const std::string reason="",
                    const pjsua_msg_data *msg_data=0);

    int hangupCall(int call_id,
                    int code,
                    const std::string reason="",
                    const std::string content_type="",
                    const std::string content="");

    int answerCall2(int call_id,
                    int code,
                    const std::string reason="",
                    const pjsua_msg_data *msg_data=0);

    int answerCall(int call_id,
                    int code,
                    const std::string reason="",
                    const std::string content_type="",
                    const std::string content="");

    int holdCall(int call_id, const std::string content_type="", const std::string content="");

    int resumeCall(int call_id, const std::string content_type="", const std::string content="");

    bool isCallActive(int call_id);

    bool isCallHasMedia(int call_id);

    void configCallInfoByID(int call_id, PjApiCallInfo **call_info);

    //void sendIM();
    //IM Section

    int sendIM(const std::string to_uri, const std::string mime_type, const std::string content);

    //Todo send IM with message body
    //void sendIM2(std::string to_uri, std::string mime_type, std::string content, message, data);

    int sendIMTyping(const std::string to_uri, bool is_typing);

    int sendIMInCall(int call_id, const std::string mime_type, const std::string content);

    int sendIMTypingInCall(int call_id, bool is_typing);

    int sendPackage(int call_id, const std::string name, const std::string content_type, const void * content);

    int sendPackageStateless(const std::string target_uri, const std::string from, const std::string to, const std::string contact,
                                const std::string pkg_name, const std::string content_type, const void* content);

private:

    void configAccount();

    PjApiUaAccount *m_account;

    PjApiUaAccountCallback *m_accountCallback;

    int m_transportID;

};

#endif //PJAPIUAACCOUNTHANDLER_H
